Partie 9 Manipuler les données

dplyr est une extension facilitant le traitement et la manipulation de données contenues dans une ou plusieurs tables (qu’il s’agisse de data frame ou de tibble). Elle propose une syntaxe claire et cohérente, sous formes de verbes, pour la plupart des opérations de ce type. Par ailleurs, les fonctions de dlpyr sont en général plus rapides que leur équivalent sous R de base, elles permettent donc de traiter des données de grande dimension.

9.1 Préparation

dplyr fait partie du tidyverse, elle est donc chargée automatiquement avec :

library(tidyverse)

On peut également la charger explicitement avec :

library(dplyr)

Dans ce qui suit on utilisera les données du jeu de données nycflights13. Celui-ci correspond aux données de tous les vols au départ d’un des trois aéroports de NEw-York en 2013. Il est réparti en trois tables :

  • flights contient des informations sur le vol : date, départ, destination, horaires, retard…
  • airports contient des informations sur les aéroports
  • airlines contient des données sur les compagnies aériennes

On va charger les trois tables du jeu de données :

library(nycflights13)
## Chargement des trois tables du jeu de données
data(flights)
data(airports)
data(airlines)

9.2 Les verbes de dplyr

La manipulation de données avec dplyr se fait en utilisant un nombre réduit de verbes, qui correspondent chacun à une action différente appliquée à un tableau de données.

9.2.1 slice

Le verbe slice sélectionne des lignes du tableau selon leur position. On lui passe un chiffre ou un vecteur de chiffres.

Si on souhaite sélectionner la 345e ligne du tableau airports :

slice(airports, 345)

Si on veut sélectionner les 5 premières lignes :

slice(airports, 1:5)

9.2.2 filter

filter sélectionne des lignes d’un tableau de données selon une condition. On lui passe en paramètre un test, et seules les lignes pour lesquelles ce test renvoie vrai sont conservées.7

Si on veut choisir les vols du mois de janvier :

filter(flights, month == 1)

Si on veut les vols avec un retard au départ compris entre 10 et 15 minutes :

filter(flights, dep_delay >= 10 & dep_delay <= 15)

Si on passe plusieurs arguments à filter, celui-ci rajoute automatiquement une condition et. La ligne ci-dessus peut donc également être écrite de la manière suivante, avec le même résultat :

filter(flights, dep_delay >= 10, dep_delay <= 15)

9.2.3 select et rename

select permet de sélectionner des colonnes d’un tableau de données. Ainsi, si on veut extraire les colonnes latet lon du tableau airports :

select(airports, lat, lon)

Si on fait précéder le nom d’un -, la colonne est éliminée plutôt que sélectionnée :

select(airports, -lat, -lon)

select comprend toute une série de fonctions facilitant la sélection de multiples colonnes. Par exemple, starts_with, ends_width, contains ou matches permettent d’exprimer des conditions sur les noms de variables :

select(airports, starts_with("dep_"))

select peut être utilisée pour réordonner les colonnes d’une table. Par exemple, si on souhaite faire passer la colonne name en première position de la table airports, on peut faire :

select(airports, name, everything())

Une variante de select est rename, qui permet de renommer facilement des colonnes. On l’utilise en lui passant des paramètres de la forme nouveau_nom = ancien_nom :

rename(airports, longitude = lon, latitude = lat)

Si les noms de colonnes comportent des espaces ou des caractères spéciaux, on peut les entourer de guillemets (") ou de quotes inverses (`).

9.2.4 arrange

arrange réordonne les lignes d’un tableau selon une ou plusieurs colonnes.

Ainsi, si on veut trier le tableau flights selon le retard au départ croissant :

arrange(flights, dep_delay)

On peut trier selon plusieurs colonnes. Par exemple selon le mois, puis selon le retard au départ :

arrange(flights, month, dep_delay)

Si on veut trier selon une colonne par ordre décroissant, on lui applique la fonction desc() :

arrange(flights, desc(dep_delay))

Combiné avec slice, arrange permet par exemples de sélectionner les trois vols ayant eu le plus de retard :

flights <- arrange(flights, desc(dep_delay)) 
slice(flights, 1:3)

9.2.5 mutate

mutate permet de créer de nouvelles colonnes dans le tableau de données à partir des variables existantes.

Par exemple, la table airports contient l’altitude de l’aéroport en pieds. Si on veut créer une nouvelle variable avec l’altitude en mètres :

airports <- mutate(airports, alt_m = alt / 3.2808)
select(airports, name, alt, alt_m)

On peut indiquer plusieurs nouvelles colonnes en une seule fois, et les expressions successives peuvent prendre en compte les résultats des calculs précédents.

flights <- mutate(flights, 
                  distance_km = distance / 0.62137,
                  vitesse = distance_km / air_time * 60)
select(flights, distance, distance_km, vitesse)

9.3 Enchaîner les opérations avec le pipe : %>%

Quand on manipule un tableau de données, il est fréquent d’enchaîner plusieurs opérations. On va par exemple filtrer une sous-population, sélectionner des colonnes et trier selon une variable.

Dans ce cas on peut le faire de deux manières différentes. La première est d’effectuer toutes les opérations en une fois en les “emboîtant” :

arrange(select(filter(flights, dest == "LAX"), dep_delay, arr_delay), dep_delay)

Cette notation a plusieurs inconvénients :

  • elle est peu lisible
  • les opérations apparaissent dans l’ordre inverse de leur réalisation. Ici on effectue d’abord le filter, puis le select, puis le arrange, alors qu’à la lecture du code c’est le arrange qui apparaît en premier.
  • Il est difficile de voir quel paramètre se rapporte à quelle fonction

Une autre manière de faire est d’effectuer les opérations les unes après les autres, en sotckant les résultats intermédiaires dans un objet temporaire :

tmp <- filter(flights, dest == "LAX")
tmp <- select(tmp, dep_delay, arr_delay)
arrange(tmp, dep_delay)

C’est nettement plus lisible, l’ordre des opérations est le bon, et les paramètres sont bien rattachés à leur fonction. Par contre, ça reste un peu “verbeux”, et on crée un objet temporaire dont on n’a pas réellement besoin.

Pour simplifier et améliorer encore la lisibilité du code, on va utiliser un nouvel opérateur, baptisé pipe.8 Le pipe se note %>%, et son fonctionnement est le suivant : si j’exécute expr %>% f, alors le résultat de l’expression expr, à gauche du pipe, sera passé comme premier argument à la fonction f, à droite du pipe, ce qui revient à exécuter f(expr).

Ainsi les deux expressions suivantes sont rigoureusement équivalentes :

filter(flights, dest == "LAX")
flights %>% filter(dest == "LAX")

Ce qui est intéressant dans l’histoire, c’est qu’on va pouvoir enchaîner les pipes. Plutôt que d’écrire :

select(filter(flights, dest == "LAX"), dep_delay, arr_delay)

On va pouvoir faire :

flights %>% filter(dest == "LAX") %>% select(dep_delay, arr_delay)

À chaque fois, le résultat de ce qui se trouve à gauche du pipe est passé comme premier argument à ce qui se trouve à droite. Le résultat final est le même, mais l’ordre des opérations correspond à l’ordre naturel de leur exécution, et on n’a pas eu besoin de créer d’objets intermédiaires.

Si la liste des fonctions enchaînées est longue, on peut les répartir sur plusieurs lignes à condition que l’opérateur %>% soit en fin de ligne :

flights %>% 
  filter(dest == "LAX") %>% 
  select(dep_delay, arr_delay) %>% 
  arrange(dep_delay)

Enfin, on peut récupérer le résultat final de l’ensemble de la chaîne de fonctions pour, par exemple, le stocker dans un objet. On peut donc faire quelque chose comme ça :

delay_la <- flights %>% 
  filter(dest == "LAX") %>% 
  select(dep_delay, arr_delay) %>% 
  arrange(dep_delay)

Dans ce cas, delay_la contiendra le tableau final, obtenu après application des trois instructions filter, select et arrange.

Cette utilisation du pipe n’est pas obligatoire, mais elle rend les scripts plus lisibles et plus rapides à saisir. On l’utilisera donc dans ce qui suit.

9.4 Opérations groupées

9.4.1 group_by

Un élément très important de dplyr est la fonction group_by. Elle permet de définir des groupes de lignes à partir des valeurs d’une ou plusieurs colonnes. Par exemple, on peut grouper les vols selon leur mois :

flights %>% group_by(month)

Par défaut ceci ne fait rien de visible, à part l’apparition d’une mention Groups lors de l’affichage. Mais à partir du moment où des groupes ont été définis, les verbes comme slice, mutate ou summarise vont en tenir compte lors de leurs calculs.

Par exemple, si on applique slice à un tableau préalablement groupé, il va sélectionner les lignes aux positions indiquées pour chaque groupe :

flights %>% group_by(month) %>% slice(1)

Idem pour mutate : les opérations appliquées lors du calcul des valeurs des nouvelles colonnes sont aplliquée groupe de lignes par groupe de lignes. Dans l’exemple suivant, on ajoute une nouvelle colonne qui contient le retard maximum du mois correspondant :

flights %>% 
  group_by(month) %>% 
  mutate(max_delay_month = max(dep_delay, na.rm = TRUE)) %>% 
  select(dep_delay, month, max_delay_month)

Attention : la clause group_by marche pour les verbes déjà vus précédemment, sauf pour arrange, qui par défaut trie la table sans tenir compte des groupes. Pour obtenir un tri par groupe, il faut lui ajouter l’argument .by_group = TRUE.

On peut voir la différence en comparant les deux résultats suivants :

flights %>% 
  group_by(month) %>% 
  arrange(desc(dep_delay))
flights %>% 
  group_by(month) %>% 
  arrange(desc(dep_delay), .by_group = TRUE)

9.4.2 summarise et count

summarise permet d’agréger les lignes du tableau en effectuant une opération “résumée” sur une ou plusieurs colonnes. Par exemple, si on souhaite connaître les retards moyens au départ et à l’arrivée pour l’ensemble des vols du tableau flights :

flights %>% 
  summarise(retard_dep = mean(dep_delay, na.rm=TRUE),
            retard_arr = mean(arr_delay, na.rm=TRUE))

Cette fonction est en général utilisée avec group_by, puisqu’elle permet du coup d’agréger et résumer les lignes du tableau groupe par groupe. Si on souhaite calculer le délai maximum, le délai minimum et le délai moyen au départ pour chaque mois, on pourra faire :

flights %>%
  group_by(month) %>%
  summarise(max_delay = max(dep_delay, na.rm=TRUE),
            min_delay = min(dep_delay, na.rm=TRUE),
            mean_delay = mean(dep_delay, na.rm=TRUE))

summarise dispose d’un opérateur spécial, n(), qui retourne le nombre de lignes du groupe. Ainsi si on veut le nombre de vols par destination :

flights %>%
  group_by(dest) %>%
  summarise(nb = n()) %>%
  arrange(desc(nb))

n() peut aussi être utilisée avec filter et mutate.

À noter que quand on veut compter le nombre de lignes par groupe, on peut utiliser directement la fonction count. Ainsi le code suivant est identique au précédent :

flights %>%
  count(dest) %>%
  arrange(desc(n))

On peut également compter selon plusieurs variables :

flights %>% 
  count(origin, dest) %>% 
  arrange(desc(n))

9.4.3 Grouper selon plusieurs variables

On peut grouper selon plusieurs variables à la fois, il suffit de les indiquer dans la clause du group_by :

flights %>%
  group_by(month, dest) %>%
  summarise(nb = n()) %>%
  arrange(desc(nb))

On peut utiliser plusieurs opérations de groupage dans la même série de fonctions. Ainsi, si on souhaite calculer le couple origine/destination avec le nombre maximum de vols selon le mois de l’année, on devra procéder en deux étapes : d’abord grouper selon mois et destination pour calculer le nombre de vols, puis grouper uniquement selon le mois pour sélectionner la ligne avec la valeur maximale.

flights %>%
  group_by(month, origin, dest) %>%
  summarise(nb = n()) %>%
  group_by(month) %>%
  filter(nb == max(nb))

9.5 Autres fonctions utiles

dplyr contient beaucoup d’autres fonctions utiles pour la manipulation de données.

9.5.1 sample_n, sample_frac

Ces verbes permettent de sélectionner un nombre de lignes ou une fraction des lignes d’un tableau aléatoirement. Ainsi si on veut choisir 5 lignes au hasard dans le tableau airports :

airports %>% sample_n(5)

Si on veut tirer au hasard 10% des lignes de flights :

flights %>% sample_frac(0.1)

9.5.2 lead et lag

lead et lag permettent de décaler les observations d’une variable d’un cran vers l’arrière (pour lead) ou vers l’avant (pour lag).

lead(1:5)
## [1]  2  3  4  5 NA
lag(1:5)
## [1] NA  1  2  3  4

Ceci peut être utile pour des données de type “séries temporelles”. Par exemple, on peut facilement calculer l’écart entre chaque le retard au départ de chaque vol et celui du vol précédent :

flights %>%
  mutate(dep_delay_prev = lead(dep_delay),
         dep_delay_diff = dep_delay - dep_delay_prev) %>%
  select(dep_delay_prev, dep_delay, dep_delay_diff)

9.5.3 tally

tally est une fonction qui permet de compter le nombre d’observations d’un groupe :

flights %>% 
  group_by(month, origin, dest) %>% 
  tally

Lors de son premier appel, elle sera équivalente à un summarise(n = n()). Là où la fonction est intelligente, c’est que si on l’appelle plusieurs fois successivement, elle prendra en compte l’existence d’un n déjà calculé et effectuera automatiquement un summarise(n = sum(n)) :

flights %>% 
  group_by(month, origin, dest) %>% 
  tally %>%
  tally
## Using `n` as weighting variable

9.5.4 distinct

distinct filtre les lignes du tableau pour ne conserver que les lignes distinctes, en supprimant toutes les lignes en double.

flights %>%
  select(day, month) %>%
  distinct

9.5.5 do

do est un verbe supplémentaire générique qui permet d’appliquer des opérations complexes aux lignes d’un tableau.

9.6 Tables multiples

9.6.1 Concaténation : bind_rows et bind_cols

Les fonctions bind_rows et bind_cols permettent d’ajouter des lignes (respectivement des colonnes) à une table à partir d’une ou plusieurs autres tables.

L’exemple suivant (certes très artificiel) montre l’utilisation de bind_rows :

t1 <- airports %>% slice(1:2)
t2 <- airports %>% slice(5:6)
t3 <- airports %>% slice(100:101) %>% select(-tz, -dst)
bind_rows(t1, t2, t3, .id = "source")

On remarquera que si des colonnes sont manquantes pour certaines tables, comme les colonnes tz et dst de t3, des NA sont automatiquement insérées. Le paramètre optionnel .id permet d’ajouter une colonne (ici nommée source) qui indique la table source des différentes lignes du tableau final.

bind_cols fonctionne de manière similaire :

t1 <- flights %>% slice(1:5) %>% select(dep_delay, dep_time)
t2 <- flights %>% slice(1:5) %>% select(origin, dest)
t3 <- flights %>% slice(1:5) %>% select(arr_delay, arr_time)
bind_cols(t1, t2, t3)

À noter que bind_cols associe les lignes uniquement par position. Les lignes des différents tableaux associés doivent donc correspondre (et leur nombre doit donc être identique). Pour associer des tables par valeur, on doit utiliser les jointures.

9.6.2 Jointures

Très souvent, les données relatives à une analyse sont réparties dans plusieurs tables différentes. Dans notre exemple, on peut voir que la table flights contient uniquement les codes des aéroports de départ et d’arrivée :

flights %>% select(origin, dest)

Et que par ailleurs la table airports contient des informations supplémentaires relatives à ces aéroports, dont le nom complet, les coordonnées géographiques, etc.

airports

Il est donc naturel de vouloir associer les deux. On peut par exemple vouloir ajouter les noms complets des aéroports à la table flights. Dans ce cas on va faire une jointure : les lignes d’une table seront associées à une autre en se basant non pas sur leur position, mais sur les valeurs d’une ou plusieurs colonnes. Ces colonnes sont appelées des clés.

Commençons par créer une sous-table d’aéroports en ne conservant que la colonne name et en la renommant. On conserve également la colonne faa, qui est la clé nous permettant de faire le lien avec flights :

airports_dep <- airports %>% select(faa, dest_name = name)
airports_dep

Et une sous-table de vols ne conservant que les colonnes year, month et day, et la clé `dest :

flights_dep <- flights %>% select(year, month, day, dest)
flights_dep

On peut alors joindre les deux tables en utilisant la fonction left_join :

left_join(flights_dep, airports_dep, by=c("dest"="faa"))

On voit que la table résultat a bien fusionné les deux tables selon les valeurs des deux colonnes clés dest et faa. On est parti de la table flights_dep, et pour chaque ligne on a ajouté les colonnes de airports_dep pour lesquelles la valeur de faa est égale à celle de dest.

L’argument by permet de spécifier les noms des clés si elles ne portent pas le même nom dans les deux tables. On peut l’omettre si c’est le cas. Dans ce cas left_join utilisera comme clés toutes les colonnes présentes dans les deux tables à la fois :

airports_dep <- airports %>% select(dest = faa, dest_name = name)
flights_dep <- flights %>% select(year, month, day, dest)
left_join(flights_dep, airports_dep)
## Joining, by = "dest"

À noter qu’on peut continuer à utiliser le pipe avec les fonctions de jointure :

flights_dep %>% left_join(airports_dep)
## Joining, by = "dest"

9.6.3 Types de jointures

Jusqu’à présent nous avons utilisé la fonction left_join, mais il existe plusieurs types de jointures.

Partons de deux tables d’exemple, personnes et voitures :

personnes <- data_frame(nom = c("Sylvie", "Sylvie", "Monique", "Gunter", "Rayan", "Rayan"),
                        voiture = c("Twingo", "Ferrari", "Scenic", "Lada", "Twingo", "Clio"))
nom voiture
Sylvie Twingo
Sylvie Ferrari
Monique Scenic
Gunter Lada
Rayan Twingo
Rayan Clio
voitures <- data_frame(voiture = c("Twingo", "Ferrari", "Clio", "Lada", "208"),
                       vitesse = c(140, 280, 160, 85, 160))
voiture vitesse
Twingo 140
Ferrari 280
Clio 160
Lada 85
208 160

9.6.3.1 left_join

Si on fait un left_join de voitures sur personnes :

left_join(personnes, voitures)
## Joining, by = "voiture"
nom voiture vitesse
Sylvie Twingo 140
Sylvie Ferrari 280
Monique Scenic NA
Gunter Lada 85
Rayan Twingo 140
Rayan Clio 160

On voit que chaque ligne de personnes est bien présente, et qu’on lui a ajouté une ligne de voitures correspondante si elle existe. Dans le cas du Scenic, il n’y a avait pas de ligne dans voitures, donc vitesse a été mis à NA. Dans le cas de 208, présente dans voitures mais pas dans personnes, la ligne n’apparaît pas.

Si on fait un left_join cette fois de personnes sur voitures, c’est l’inverse :

left_join(voitures, personnes)
## Joining, by = "voiture"
voiture vitesse nom
Twingo 140 Sylvie
Twingo 140 Rayan
Ferrari 280 Sylvie
Clio 160 Rayan
Lada 85 Gunter
208 160 NA

Cette fois c’est l’inverse. La ligne 208 est là, mais nom est à NA. Par contre Monique est absente. Et on remarquera que la ligne Twingo, présente deux fois dans personnes, a été dupliquée pour être associée aux deux lignes de données de Sylvie et Rayan.

En résumé, quand on fait un left_join(x, y), toutes les lignes de x sont présentes, dupliquées si nécessaire quand elles apparaissent plusieurs fois dans y. Les lignes de y non présentes dans x disparaissent. Les lignes de x non présentes dans y se voient attribuer des NA.

Intuitivement, on pourrait considérer que left_join(x, y) signifie “ramener l’information de la table y sur la table x”.

En général, left_join sera le type de jointures le plus fréquemment utilisé.

9.6.3.2 right_join

La jointure right_join est l’exacte symétrique de left_join, c’est-à dire que right_join(x, y) est équivalent à left_join(x,y) :

right_join(personnes, voitures)
## Joining, by = "voiture"
nom voiture vitesse
Sylvie Twingo 140
Rayan Twingo 140
Sylvie Ferrari 280
Rayan Clio 160
Gunter Lada 85
NA 208 160

9.6.3.3 inner_join

Dans le cas de inner_join(x, y), seules les lignes présentes à la fois dans x et y sont présentes (et si nécessaire dupliquées) dans la table résultat :

inner_join(personnes, voitures)
## Joining, by = "voiture"
nom voiture vitesse
Sylvie Twingo 140
Sylvie Ferrari 280
Gunter Lada 85
Rayan Twingo 140
Rayan Clio 160

Ici la ligne 208 est absente, ainsi que le aligne Monique, qui dans le cas d’un left_join avait été conservée et s’était vue attribuer une vitesse à NA.

9.6.3.4 full_join

Dans le cas de full_join(x, y), toutes les lignes de x et toutes les lignes de y sont conservées (avec des NA ajoutés si nécessaire) même si elles sont absentes de l’autre table :

full_join(personnes, voitures)
## Joining, by = "voiture"
nom voiture vitesse
Sylvie Twingo 140
Sylvie Ferrari 280
Monique Scenic NA
Gunter Lada 85
Rayan Twingo 140
Rayan Clio 160
NA 208 160

9.6.3.5 semi_join et anti_join

semi_join et anti_join sont des jointures filtrantes, c’est-à-dire qu’elles sélectionnent les lignes de x sans ajouter les colonnes de y.

Ainsi, semi_join ne conservera que les lignes de x pour lesquelles une ligne de y existe également, et supprimera les autres. Dans notre exemple, la ligne Monique est donc supprimée :

semi_join(personnes, voitures)
## Joining, by = "voiture"
nom voiture
Sylvie Twingo
Sylvie Ferrari
Gunter Lada
Rayan Twingo
Rayan Clio

Un anti_join fait l’inverse, il ne conserve que les lignes de x absentes de y. Dans notre exemple, on ne garde donc que la ligne Monique :

anti_join(personnes, voitures)
## Joining, by = "voiture"
nom voiture
Monique Scenic

9.7 Ressources

Toutes les ressources ci-dessous sont en anglais…

Le livre R for data science, librement accessibles en ligne, contient plusieurs chapitres très complets sur la manipulation des données, notamment :

Le site de l’extension est accessible à l’adresse : http://dplyr.tidyverse.org/. Outre une liste des fonctions et les pages d’aide associées, il contient également une introduction au package et plusieurs articles dont un sur les jointures.

Enfin, une “antisèche” très synthétique est également accessible depuis RStudio, en allant dans le menu Help puis Cheatsheets et Data Transformation with dplyr.

9.8 Exercices

On commence par charger les extensions et les données nécessaires.

library(tidyverse)
library(nycflights13)

9.8.1 Les verbes de base de dplyr

Exercice 1.1

Sélectionner les lignes 100 à 105 du tableau des vols (flights).

Exercice 1.2

  • Sélectionnez les vols du mois de juillet (variable month).
  • Sélectionnez les vols avec un retard à l’arrivée (variable arr_delay) compris entre 5 et 15 minutes.
  • Sélectionnez les vols des compagnies Delta, United et American (codes AA, DL et UA).
filter(flights, carrier %in% c("AA", "DL", "UA"))

Exercice 1.3

Triez la table flights par retard au départ décroissant.

Exercice 1.4

  • Sélectionner les colonnes name, lat et lon de la table airports
select(airports, name, lat, lon)
  • Sélectionner toutes les colonnes de la table airports sauf les colonnes tz et tzone
select(airports, -tz, -tzone)
  • Toujours dans la table airports, renommer la colonne lat en latitude et lon en longitude.
rename(airports, latitude = lat, longitude = lon)

Exercice 1.5

Dans la table flights, créer une nouvelle variable duree_h contenant la durée du vol (variable air_time) en heures. Sélectionner dans la table obtenue uniquement les deux colonnes air_time et duree_h.

tmp <- mutate(flights, duree_h = air_time / 60)
select(tmp, air_time, duree_h)

9.8.2 Enchaîner des opérations

Exercice 2.1

Réécrire le code de l’exercice précédent en utilisant le pipe %>% :

flights %>% 
  mutate(duree_h = air_time / 60) %>% 
  select(air_time, duree_h)

Exercice 2.2

Sélectionnez les vols à destination de San Francico (code SFO) et triez-les selon le retard au départ décroissant (variable dep_delay).

Exercice 2.3

Sélectionnez les vols des mois de septembre et octobre, conservez les colonnes dest et dep_delay, créez une nouvelle variables retard_h contenant le retard au départ en heures, triez selon retard_h par ordre décroissant et conservez uniquement les 5 premières lignes.

9.8.3 group_by et summarise

Exercice 3.1

Affichez le nombre de vols par mois.

Triez la table résultat selon le nombre de vols croissant.

Exercice 3.2

Calculer le retard au départ moyen selon le mois.

Exercice 3.3

Calculer le nombre de vols à destination de Los Angeles (code LAX) pour chaque mois de l’année.

Exercice 3.3

Calculer le nombre de vols selon le mois et la destination.

Ne conserver, pour chaque mois, que la destination avec le nombre maximal de vols.

Exercice 3.4

Calculer le nombre de vols selon le mois. Ajouter une colonne comportant le pourcentage de vols annuels réalisés par mois.

Exercice 3.5

Calculer, pour chaque destination et chaque mois, le retard moyen à l’arrivée. Pour chaque mois, trier les destinations selon le retard décroissant, et ne conserver que les trois destinations avec le retard le plus important.

9.8.4 Jointures

Exercice 5.1

Faire la jointure de la table airline sur la table flights à l’aide de left_join.

## Joining, by = "carrier"

Exercice 5.2

À partir de la table résultat de l’exercice précédent, calculer le retard moyen au départ pour chaque compagnie, trier selon ce retard décroissant et afficher le nom de la compagnie et le retard correspondant.

## Joining, by = "carrier"

Exercice 5.3

Faire la jointe de la table airports sur la table flights en utilisant comme clé le code de l’aéroport de destination.

À partir de cette table, afficher pour chaque mois le nom de l’aéroport de destination ayant eu le plus petit nombre de vol.

Exercice 5.4

Créer une table indiquant, pour chaque trajet, le nom de l’aéroport de départ et celui de l’aéroport d’arrivée.

flights %>% 
  left_join(airports, by = c("dest" = "faa")) %>% 
  rename(dest_name = name) %>% 
  left_join(airports, by = c("origin" = "faa")) %>% 
  rename(orig_name = name) %>% 
  select(orig_name, dest_name)  

9.8.5 Bonus

Exercice 6.1

Calculer le nombre de vols selon l’aéroport de destination, et fusionnez la table airports sur le résultat avec left_join. Stocker le résultat final dans un objet nommé flights_dest.

Créez une carte interactive des résultats avec leaflet et le code suivant :

library(leaflet)
leaflet(data = flights_dest) %>%
  addTiles %>%
  addCircles(lng=~lon, lat=~lat, radius=~n * 10, popup=~name)

Créez une carte statique des résultats avec ggmap et le code suivant :

library(ggmap)
map <- get_map(location = "Kansas", zoom=4, color="bw")
ggmap(map, extent = "device") +
  geom_point(data = flights_dest, aes(x=lon, y=lat, size=n), 
             color = "red", alpha = 0.2)

  1. Pour plus d’informations sur les tests et leur syntaxe, voir la section 10.2

  2. Le pipe a été introduit à l’origine par l’extension magrittr, et repris par dplyr